package com.base.cn.platform.os.service.manage.role;

import com.base.cn.platform.os.common.mybatis.BaseBiz;
import com.base.cn.platform.os.common.mybatis.Pagination;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.dao.manage.role.SysRoleDao;
import com.base.cn.platform.os.entity.manage.function.SysFunction;
import com.base.cn.platform.os.entity.manage.join.SysRoleFunction;
import com.base.cn.platform.os.entity.manage.join.SysRoleSubject;
import com.base.cn.platform.os.entity.manage.role.SysRole;
import com.base.cn.platform.os.entity.manage.subject.SysSubject;
import com.base.cn.platform.os.entity.manage.user.SysUser;
import com.base.cn.platform.os.service.manage.function.SysFunctionBiz;
import com.base.cn.platform.os.service.manage.join.SysRoleFunctionBiz;
import com.base.cn.platform.os.service.manage.join.SysRoleSubjectBiz;
import com.base.cn.platform.os.service.manage.join.SysUserRoleBiz;
import com.base.cn.platform.os.service.manage.subject.SysSubjectBiz;
import com.base.cn.platform.os.service.manage.user.SysUserBiz;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 系统角色业务类
 *
 * @author s.li
 * @create 2018-02-05 16:31
 */
@Service
public class SysRoleBiz extends BaseBiz<SysRole,SysRoleDao> {
    @Autowired
    private SysUserRoleBiz sysUserRoleBiz;
    @Autowired
    private SysRoleFunctionBiz sysRoleFunctionBiz;
    @Autowired
    private SysRoleSubjectBiz sysRoleSubjectBiz;
    @Autowired
    private SysUserBiz sysUserBiz;
    @Autowired
    private SysSubjectBiz sysSubjectBiz;
    @Autowired
    private SysFunctionBiz sysFunctionBiz;

    public List<SysRole> findSysRoleListByIds(String roleIds,boolean subjectData,boolean sysFunctionData){
        if(StringUtils.isNotEmpty(roleIds)){
            roleIds = StringUtils.subHeadTailString(roleIds,",");
            if(StringUtils.isNotEmpty(roleIds)){
                List<SysRole> sysRoleList = this.find(" id in ("+roleIds+")",null,null);
                sysRoleList = this.setSubjectAndFunction(sysRoleList,subjectData,sysFunctionData);
                return sysRoleList;
            }
        }
        return null;
    }

    /**
     * 查询角色数据
     * @param id 角色ID
     * @param subjectData 是否获取角色关联的专业数据
     * @param sysFunctionData 是否获取角色关联的权限
     * @return SysRole角色数据
     */
    public SysRole findById(BigDecimal id,boolean subjectData,boolean sysFunctionData){
        if(id!=null){
            List<SysRole> sysRoleList = this.findSysRoleListByIds(id.toString(),subjectData,sysFunctionData);
            if(ObjectUtils.isNotEmpty(sysRoleList)){
                return sysRoleList.get(0);
            }
        }
        return null;
    }

    /**
     * 查询角色列表
     * @param sysRole 查询条件
     * @return List<SysRole>
     */
    public List<SysRole> findSysRoleListCondition(SysRole sysRole){
        StringBuilder whereSql = new StringBuilder(" 1=1");
        if(ObjectUtils.isNotEmpty(sysRole)){
            if(StringUtils.isNotEmpty(sysRole.getRoleName())){
                whereSql .append(" and roleName like '").append(sysRole.getRoleName().trim()).append("'");
            }
            if(sysRole.getStatus()!=null && sysRole.getStatus().intValue()>0){
                whereSql .append(" and status = ").append(sysRole.getStatus());
            }
            if(StringUtils.isNotEmpty(sysRole.getNotIds())){
                whereSql .append(" and id not in(").append(sysRole.getNotIds()).append(")");
            }
        }
        return this.find(whereSql.toString(),null,null);
    }

    /**
     * 分页查询角色列表
     * @param sysRole 查询条件
     * @param page 分页条件
     * @return PageInfo<SysRole>
     */
    public PageInfo<SysRole> findSysRoleListCondition(SysRole sysRole, Pagination page){
        StringBuilder whereSql = new StringBuilder(" 1=1");
        if(ObjectUtils.isNotEmpty(sysRole)){
            if(StringUtils.isNotEmpty(sysRole.getRoleName())){
                whereSql .append( " and roleName like '%").append(sysRole.getRoleName().trim()).append("%'");
            }
            if(ObjectUtils.isNotEmpty(sysRole.getStatus())){
                whereSql .append( " and status=").append(sysRole.getStatus());
            }
        }
        whereSql.append(" order by createTime desc");
        PageInfo<SysRole> sysRolePageInfo = this.findPage(whereSql.toString(),page,null);
        //设置角色的创建者
        if(sysRolePageInfo.getTotal()>0){
            List<SysRole> sysRoleList = sysRolePageInfo.getList();
            String userIds = sysRoleList.stream().filter(x->ObjectUtils.isNotEmpty(x.getCreateUserId())).map(e->e.getCreateUserId().toString()).collect(Collectors.joining(","));
            List<SysUser> sysUserList = sysUserBiz.find(" id in ("+userIds+")",sysRoleList.size(),null);
            if(ObjectUtils.isNotEmpty(sysUserList)){
                Map<BigDecimal,SysUser> sysUserMap = sysUserList.stream().collect(Collectors.toMap(e->e.getId(),e->e));
                for(SysRole sysRole1 : sysRoleList){
                    SysUser sysUser = sysUserMap.get(sysRole1.getCreateUserId());
                    sysRole1.setSysUser(sysUser);
                }
            }
            sysRolePageInfo.setList(sysRoleList);
        }
        return sysRolePageInfo;
    }

    /**
     * 保存角色
     * @param sysRole 角色数据对象
     * @return 保存成功的角色数据
     */
    public SysRole saveRole(SysRole sysRole){
        //修改
        if(DataUtil.idIsNotNull(sysRole.getId())){
            SysRole _sysRole = this.findById(sysRole.getId());
            _sysRole.setRoleName(sysRole.getRoleName());
            _sysRole.setDepict(sysRole.getDepict());
            this.updateById(_sysRole,null);
        }else{//添加
            sysRole.setStatus(1);//默认状态为1（正常）
            this.save(sysRole);
        }
        return sysRole;
    }

    /**
     * 修改角色状态
     * @param roleIds 角色ID串
     * @param status 角色状态 1正常，2禁用
     */
    public void updateRoleStatus(String roleIds,Integer status){
        SysRole sysRole = new SysRole();
        sysRole.setStatus(status);
        this.updateByWhereSql(sysRole," id in("+roleIds+") and id !=1");
    }

    /**
     * 通过角色ID串，删除角色数据
     * @param ids 角色ID串，多个ID以“,”隔开
     */
    @Transactional(rollbackFor = IllegalArgumentException.class )
    public void deleteSysRole(String ids){
        //删除角色
        this.deleteWhereSql(" id in ("+ids+") and id > 4");
        //删除用户角色关联数据
        sysUserRoleBiz.deleteWhereSql(" roleId in ("+ids+") and roleId > 4");
        //删除角色权限关联数据
        sysRoleFunctionBiz.deleteWhereSql(" roleId in ("+ids+") and roleId > 4");
    }

    //--------------------------------------

    /**
     * 设置权限的专业和权限数据
     * @param sysRole
     * @param subjectData
     * @param functionData
     * @return
     */
    public SysRole setSubjectAndFunction(SysRole sysRole,boolean subjectData,boolean functionData){
        if(ObjectUtils.isNotEmpty(sysRole)){
            List<SysRole> sysRoleList = new ArrayList<>();
            sysRoleList.add(sysRole);
            sysRoleList = this.setSubjectAndFunction(sysRoleList,subjectData,functionData);
            sysRole = sysRoleList.get(0);
        }
        return sysRole;
    }

    /**
     * 设置角色的专业和权限列表
     * @param sysRoleList
     * @param subjectData
     * @param functionData
     * @return
     */
    public List<SysRole> setSubjectAndFunction(List<SysRole> sysRoleList,boolean subjectData,boolean functionData){
        if(ObjectUtils.isNotEmpty(sysRoleList)){
            if(subjectData){
                sysRoleList = this.setSubjectData(sysRoleList);
            }
            if(functionData){
                sysRoleList = this.setSysFunctionData(sysRoleList);
            }
        }
        return sysRoleList;
    }

    /**
     * 设置角色的权限数据（把第三层的权限合并到第二层中）
     * @param sysRole 角色对象
     * @return
     */
    private SysRole setSysFunctionData(SysRole sysRole){
        if(ObjectUtils.isNotEmpty(sysRole)){
            List<SysRole> sysRoleList = new ArrayList<>();
            sysRoleList.add(sysRole);
            sysRoleList = this.setSysFunctionData(sysRoleList);
            sysRole = sysRoleList.get(0);
        }
        return sysRole;
    }

    /**
     * 设置角色的权限数据
     * @param sysRoleList 角色列表
     * @return List<SysRole>
     */
    private List<SysRole> setSysFunctionData(List<SysRole> sysRoleList){
        if(ObjectUtils.isNotEmpty(sysRoleList)){
            String roleIds = sysRoleList.stream().map(e->e.getId().toString()).collect(Collectors.joining(","));
            //获取角色的权限ID列表
            List<SysRoleFunction> roleFunctionList = sysRoleFunctionBiz.findSysRoleFunctionListByRoleIds(roleIds);
            if(ObjectUtils.isNotEmpty(roleFunctionList)){
                String functionIds = roleFunctionList.stream().map(e->e.getFunctionId().toString()).collect(Collectors.joining(","));
                //得到角色的权限
                Map<BigDecimal,SysFunction> sysFunctionMap = sysFunctionBiz.findSysFunctionMapByIds(functionIds);
                if(ObjectUtils.isNotEmpty(sysFunctionMap)){
                    //通过角色进行分组
                    Map<BigDecimal,List<SysRoleFunction>> roleFunctionListMap = roleFunctionList.stream().collect(Collectors.groupingBy(e->e.getRoleId()));
                    sysRoleList.forEach(e->{
                        //角色与权限关联的数据
                        List<SysRoleFunction> roleFunctions = roleFunctionListMap.get(e.getId());
                        if(ObjectUtils.isNotEmpty(roleFunctions)){
                            List<SysFunction> sysFunctionList = new ArrayList<>();
                            roleFunctions.forEach(em -> {
                                SysFunction sysFunction = sysFunctionMap.get(em.getFunctionId());
                                if(ObjectUtils.isNotEmpty(sysFunction)){
                                    sysFunctionList.add(sysFunction);
                                }
                            });
                            if(ObjectUtils.isNotEmpty(sysFunctionList)){
                                List<SysFunction> _sysFunctionList = sysFunctionBiz.handleSysFunction(sysFunctionList);
                                e.setSysFunctionList(_sysFunctionList);
                            }
                        }
                    });
                }
            }

        }
        return sysRoleList;
    }

    /**
     * 设置角色对象的专业列表
     * @param sysRole 角色对象
     * @return SysRole
     */
    private SysRole setSubjectData(SysRole sysRole){
        if(ObjectUtils.isNotEmpty(sysRole)){
            List<SysRole> sysRoleList = new ArrayList<>();
            sysRoleList.add(sysRole);
            sysRoleList = this.setSubjectData(sysRoleList);
            sysRole = sysRoleList.get(0);
        }
        return sysRole;
    }

    /**
     * 设置角色的分层好的专业数据列表
     * @param sysRoleList 角色列表
     * @return List<SysRole>
     */
    private List<SysRole> setSubjectData(List<SysRole> sysRoleList){
        if(ObjectUtils.isNotEmpty(sysRoleList)){
            String roleIds = sysRoleList.stream().map(e->e.getId().toString()).collect(Collectors.joining(","));
            //角色关联的专业ID
            List<SysRoleSubject> roleSubjectList = sysRoleSubjectBiz.findSysRoleSubjectListByRoleIds(roleIds);
            if(ObjectUtils.isNotEmpty(roleSubjectList)){
                String subjectIds = roleSubjectList.stream().map(e->e.getSubjectId().toString()).collect(Collectors.joining(","));
                Map<BigDecimal,SysSubject> subjectMap = sysSubjectBiz.findSubjectListByIds(subjectIds);
                if(ObjectUtils.isNotEmpty(subjectMap)){
                    //通过角色ID分组
                    Map<BigDecimal,List<SysRoleSubject>> roleSubjectListMap = roleSubjectList.stream().collect(Collectors.groupingBy(e->e.getRoleId()));
                    //循环角色
                    sysRoleList.forEach(e->{
                        //角色的专业ID数据
                        List<SysRoleSubject> roleSubjects = roleSubjectListMap.get(e.getId());
                        if(ObjectUtils.isNotEmpty(roleSubjects)){
                            List<SysSubject> subjectList = new ArrayList<>();
                            //获取专业数据
                            roleSubjects.forEach(em ->{
                                SysSubject subject = subjectMap.get(em.getSubjectId());
                                if(ObjectUtils.isNotEmpty(subject)){
                                    subjectList.add(subject);
                                }
                            });
                            if(ObjectUtils.isNotEmpty(subjectList)){
                                //分层归类，
                                List<SysSubject> _subjectList = sysSubjectBiz.handleSubjectList(subjectList);
                                //设置角色的专业列表（分层后的专业列表）
                                e.setSubjects(_subjectList);
                            }
                        }
                    });
                }
            }

        }
        return sysRoleList;
    }
}
